home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / GAPLib.lha / GAPLib_Beta / wizards / Templates / report.c < prev    next >
C/C++ Source or Header  |  1999-04-22  |  6KB  |  287 lines

  1. /*
  2.  * Report file generation utility code.
  3.  * See report.doc for more info.
  4.  *
  5.  * (C)1998-1999 Peter Bengtsson
  6.  *
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #include <GAP.h>
  14.  
  15. #include "report.h"
  16.  
  17. static const char * const exts[REPFILES] = {
  18.     "avg",
  19.     "med",
  20.     "typ",
  21.     "max",
  22.     "min",
  23.     "dev"
  24. };
  25.  
  26. static const char * const descs[REPFILES] = {
  27.     "Average",
  28.     "Median",
  29.     "TypeCount",
  30.     "Max",
  31.     "Min",
  32.     "StdDev"
  33. };
  34.  
  35. struct Report *MakeReport(char *,struct TagItem *);
  36. void DoReport(struct Report *,struct Population *,unsigned int);
  37. void EndReport(struct Report *rs);
  38.  
  39. struct Report *MakeReport(char *basename,struct TagItem *TagList)
  40. {
  41. struct Report *rs;
  42. char    *buf=NULL;
  43. int i;
  44. Tag    tag=TAG_DONE;
  45.  
  46. rs = malloc(sizeof(struct Report));
  47.  
  48. rs->flags=0;
  49. rs->gencount=0;
  50.  
  51. for(i=0;i!=REPFILES;i++) {
  52.     rs->vbuffer[i]=NULL;
  53.     rs->cbuffer[i] = 0;
  54. }
  55.  
  56. i=0;
  57.  
  58. if(rs!=0) {
  59.  
  60.     if(TagList!=NULL) {
  61.         tag = TagList[0].ti_Tag;
  62.     }
  63.  
  64.     while(tag!=TAG_DONE) {
  65.  
  66.         switch(tag) {
  67.  
  68.         case    REP_Generations:
  69.             rs->gencount = TagList[i].ti_Data;
  70.         break;
  71.  
  72.         case    REP_Multipass:
  73.             rs->flags &= ~RFLG_MPASS;
  74.             if(TagList[i].ti_Data!=FALSE) {
  75.                 rs->flags |= RFLG_MPASS;
  76.             }
  77.         break;
  78.  
  79.         default:
  80.             fprintf(stderr,"MakeReport: Unrecognized tag 0x%08lx.\n",tag);
  81.         }
  82.  
  83.         tag = TagList[++i].ti_Tag;
  84.     }
  85.  
  86.     if((rs->flags&RFLG_MPASS) && rs->gencount==0) {
  87.         fprintf(stderr,"MakeReport: Multipass mode selected but number of generations undeclared.\nDisabling multipass mode.\n");
  88.         rs->flags &= ~RFLG_MPASS;
  89.     }
  90.  
  91.     if(basename!=NULL) {
  92.         buf = malloc((strlen(basename)+8)*sizeof(char));
  93.         rs->basename = malloc((strlen(basename)+1)*sizeof(char));
  94.         strcpy(rs->basename,basename);
  95.  
  96.         if(rs!=NULL && rs->basename!=NULL && buf!=NULL) {
  97.             for(i=0;i!=REPFILES;i++) {
  98.                 sprintf(buf,"%s.%s",basename,exts[i]);
  99.                 if((rs->files[i]=fopen(buf,"wb"))==NULL) {
  100.                     while(--i>=0) {
  101.                         fclose(rs->files[i]);
  102.                     }
  103.                     free(rs->basename);
  104.                     free(rs);
  105.                     rs = NULL;
  106.                     fprintf(stderr,"MakeReport: Error opening files for writing.\n");
  107.                 }
  108.                 rs->used[i]=0;
  109.                 fprintf(rs->files[i],"# Generation, %s\n",descs[i]);
  110.             }
  111.         } else {
  112.             if(rs!=NULL) {
  113.                 if(rs->basename!=NULL) {
  114.                     free(rs->basename);
  115.                 }
  116.                 free(rs);
  117.                 rs = NULL;
  118.             }
  119.             fprintf(stderr,"MakeReport: No free store (malloc() failed).\n");
  120.         }
  121.     } else {
  122.         fprintf(stderr,"MakeReport: NULL basename.\n");
  123.     }
  124.  
  125.     if(buf!=NULL) {
  126.         free(buf);
  127.     }
  128.  
  129. }
  130.  
  131. return(rs);
  132. }
  133.  
  134. void EndReport(struct Report *rs)
  135. {
  136. int i,n;
  137. char *buf=NULL;
  138.  
  139. if(rs!=NULL) {
  140.     if(rs->flags&RFLG_MPASS) {
  141.         for(i=0;i!=REPFILES;i++) {
  142.             if(rs->used[i]!=0) {
  143.                 for(n=0;n!=rs->gencount;n++) {
  144.                     fprintf(rs->files[i],"%d %f\n",n+1,rs->vbuffer[i][n]/((double)rs->cbuffer[i]));
  145.                 }
  146.             }
  147.         }
  148.     }
  149.     buf=malloc((strlen(rs->basename)+8)*sizeof(char));
  150.     for(i=0;i!=REPFILES;i++) {
  151.         fclose(rs->files[i]);    /* fclose does an fflush. */
  152.         if(rs->used[i]==0 && buf!=NULL) {
  153.             sprintf(buf,"%s.%s",rs->basename,exts[i]);
  154.             remove(buf);
  155.         }
  156.     }
  157.  
  158.     if(rs->flags&RFLG_VBUF) {
  159.         for(i=0;i!=REPFILES;i++) {
  160.             if(rs->vbuffer[i]!=NULL) {
  161.                 free(rs->vbuffer[i]);
  162.             }
  163.         }
  164.     }
  165.  
  166.     free(rs->basename);
  167.     free(rs);
  168. }
  169.  
  170. if(buf!=NULL) {
  171.     free(buf);
  172. } else {
  173.     fprintf(stderr,"EndReport: No free store, continuing.\n");
  174. }
  175.  
  176. }
  177.  
  178. void DoReport(struct Report *rs,struct Population *Pop,unsigned int flags)
  179. {
  180. int i,n,t;
  181. struct Popstat *stat;
  182.  
  183. if(rs!=NULL && Pop!=NULL && flags!=0) {
  184.     stat = &Pop->Stat;
  185.     for(i=0;i!=REPFILES;i++) {
  186.         n = flags&(1<<i);
  187.         if(n!=0) {
  188.             rs->used[i]=1;
  189.             if(rs->flags&RFLG_MPASS) {
  190.                 if(stat->Generation==1) {
  191.                     rs->cbuffer[i]++;
  192.                 }
  193.                 if(stat->Generation>rs->gencount) {
  194.                     fprintf(stderr,"DoReport: Generation overflow.\n");
  195.                 } else {
  196.                     if(rs->vbuffer[i]==NULL) {
  197.                         if(rs->flags&RFLG_NOMEM) {
  198.                             break;
  199.                         }
  200.                         rs->flags |= RFLG_VBUF;
  201.                         rs->vbuffer[i] = malloc(rs->gencount*sizeof(double));
  202.                         if(rs->vbuffer[i]==NULL) {
  203.                             rs->flags |= RFLG_NOMEM;
  204.                             fprintf(stderr,"DoReport: No free store for multipass buffer.\n(Failed to allocate %ld bytes.)\n",rs->gencount*sizeof(double));
  205.                             break;
  206.                         } else {
  207.                             for(t=0;t!=rs->gencount;t++) {
  208.                                 rs->vbuffer[i][t] = 0.0;
  209.                             }
  210.                         }
  211.                     }
  212.                     switch(n) {
  213.                     case    AVERAGE:
  214.                         rs->vbuffer[i][stat->Generation-1] += stat->AverageFitness;
  215.                     break;
  216.                     case    MEDIAN:
  217.                         rs->vbuffer[i][stat->Generation-1] += stat->MedianFitness;
  218.                     break;
  219.                     case    TYPECOUNT:
  220.                         rs->vbuffer[i][stat->Generation-1] += (double) stat->TypeCount;
  221.                     break;
  222.                     case    MAX:
  223.                         rs->vbuffer[i][stat->Generation-1] += stat->MaxFitness;
  224.                     break;
  225.                     case    MIN:
  226.                         rs->vbuffer[i][stat->Generation-1] += stat->MinFitness;
  227.                     break;
  228.                     case    STDDEV:
  229.                         rs->vbuffer[i][stat->Generation-1] += stat->StdDeviation;
  230.                     break;
  231.                     }
  232.                 }
  233.             } else {
  234.                 switch(n) {
  235.                 case    AVERAGE:
  236.                     fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->AverageFitness);
  237.                 break;
  238.                 case    MEDIAN:
  239.                     fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MedianFitness);
  240.                 break;
  241.                 case    TYPECOUNT:
  242.                     fprintf(rs->files[i],"%ld %ld\n",stat->Generation,stat->TypeCount);
  243.                 break;
  244.                 case    MAX:
  245.                     fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MaxFitness);
  246.                 break;
  247.                 case    MIN:
  248.                     fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->MinFitness);
  249.                 break;
  250.                 case    STDDEV:
  251.                     fprintf(rs->files[i],"%ld %f\n",stat->Generation,stat->StdDeviation);
  252.                 break;
  253.                 }
  254.             }
  255.         }
  256.     }
  257. }
  258.  
  259. }
  260.  
  261. struct Report *MakeReportT(char *basename,...)
  262. {
  263. va_list ap;
  264. int i=0;
  265. struct TagItem TagList[64]; /* Assumed big enough */
  266.  
  267. va_start(ap,basename);
  268.  
  269. while((TagList[i].ti_Tag = va_arg(ap,Tag)),TagList[i].ti_Tag != TAG_DONE && TagList[i].ti_Tag != TAG_MORE) {
  270.     TagList[i].ti_Data = va_arg(ap,IPTR);
  271.     i++;
  272. }
  273.  
  274. if(TagList[i].ti_Tag == TAG_MORE) {
  275.     TagList[i].ti_Data = va_arg(ap,IPTR);
  276.     if(TagList[i].ti_Data == 0) {
  277.         fprintf(stderr,"MakeReportT: Illegal NULL value for TAG_MORE.\n");
  278.         TagList[i].ti_Tag = TAG_DONE;
  279.     }
  280. }
  281.  
  282. va_end(ap);
  283.  
  284. return (MakeReport(basename,TagList));
  285. }
  286.  
  287.